<?php
/**
 * 自动签收订单
 *
 * @author Zeon <scplay@gmail.com>
 * @date 2019/1/4
 * @copyright PanxSoft Inc.
 */
namespace App\Jobs;

use App\Http\Services\Api\V1\App\Product\OrderService;
use App\Models\Order\OrderAutoSign;
use App\Models\Order\OrderStatus;
use App\Services\Utils\Transaction;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class AutoSignOrder implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * @var int
     */
    private $order_sign_id;
    /**
     * Create a new job instance.
     *
     * @param OrderAutoSign $orderAutoSign
     */
    public function __construct(OrderAutoSign $orderAutoSign)
    {
        $this->order_sign_id = $orderAutoSign->getKey();

        /**
         * 如果数据库有更新，执行时数据是会更新的
         * 如果删除数据了， 执行时会直接 Failed (想保存 failed 历史，需要新增一张 failed_jobs 表)
         * @link https://laravel.com/docs/5.7/queues#dealing-with-failed-jobs - 参考文档
         */
//        $this->orderAutoSign = $orderAutoSign;
    }

    /**
     * Execute the job.
     *
     * @return void
     * @throws \Exception
     */
    public function handle()
    {
        /** @var OrderAutoSign $order_auto_sign */
        $order_auto_sign = (new OrderAutoSign)->find($this->order_sign_id);
        if (! $this->validateAutoSign($order_auto_sign)) {
            return;
        }

        $complete_status_id = head(OrderStatus::getOrderStatusIdsToBeEvaluate());

        Transaction::handle(function () use ($order_auto_sign, $complete_status_id) {
            (new OrderService)->updateOrderStatus(
                $order_auto_sign->order, $complete_status_id, 'Order Auto Signed'
            );

            $order_auto_sign->updateSign(true);
        });
    }

    /**
     * @param OrderAutoSign $order_auto_sign
     *
     * @return bool
     */
    private function validateAutoSign(?OrderAutoSign $order_auto_sign): bool
    {
        if (! $order_auto_sign) {
            logger()->error("OrderAutoSign[ID:$this->order_sign_id] not found!");
            return false;
        }

        if ($order_auto_sign->signed) {
            logger()->error("OrderAutoSign[ID:$this->order_sign_id] already signed!");
            return false;
        }

        if (! $order_auto_sign->order) {
            logger()->error("Order[ID:$order_auto_sign->order_id] not found!");
            return false;
        }

        if (! $order_auto_sign->order->isOrderStatusProcessing()) {
            logger()->error("Order[ID:$order_auto_sign->order_id] not in processing status!");
            return false;
        }

        return true;
    }
}
